<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{:config("app.app_name")}</title>
  <!-- 请勿在项目正式环境中引用该 layui.css 地址 -->
  <link href="__STATIC__/layui/css/layui.css" rel="stylesheet">
</head>
<style>
  .demo-login-container{width: 320px; margin: 21px auto 0;}
  .demo-login-other .layui-icon{position: relative; display: inline-block; margin: 0 2px; top: 2px; font-size: 26px;}
  .title{background: #16baaa;color:#fff;font-size: 25px;text-align: center;padding: 5px;
    border-radius: 3px;}
  .bodys{height: 100vh;position: relative;background: #000000}
  .layui-form{padding:5px 15px;margin-top: -150px;background: #fff;border-radius: 5px}
  #captcha{width:120px;height:40px}
  .biaodan{position:absolute;display: flex;justify-content: center;align-items: center;height:100%;width:100%;
  }
</style>
<body class="bodys">
<div class="biaodan">
  <form class="layui-form" action="{:url('submit')}" method="post">
    <div class="demo-login-container">
      <div class="layui-form-item">
        <div class="layui-input-wrap title">
          {:config("app.app_name")}登陆后台
        </div>
      </div>
      <div class="layui-form-item">
        <div class="layui-input-wrap">
          <div class="layui-input-prefix">
            <i class="layui-icon layui-icon-username"></i>
          </div>
          <input type="text" name="username" value="" lay-verify="required" placeholder="用户名" lay-reqtext="请填写用户名" autocomplete="off" class="layui-input" lay-affix="clear">
        </div>
      </div>
      <div class="layui-form-item">
        <div class="layui-input-wrap">
          <div class="layui-input-prefix">
            <i class="layui-icon layui-icon-password"></i>
          </div>
          <input type="password" name="password" value="" lay-verify="required" placeholder="密   码" lay-reqtext="请填写密码" autocomplete="off" class="layui-input" lay-affix="eye">
        </div>
      </div>
      <div class="layui-form-item">
        <div class="layui-row">
          <div class="layui-col-xs7">
            <div class="layui-input-wrap">
              <div class="layui-input-prefix">
                <i class="layui-icon layui-icon-vercode"></i>
              </div>
              <input type="text" name="captcha" value="" lay-verify="required" placeholder="验证码" lay-reqtext="请填写验证码" autocomplete="off" class="layui-input" lay-affix="clear">
            </div>
          </div>
          <div class="layui-col-xs5">
            <div style="margin-left: 10px;">
              <img id="captcha" src="{:captcha_src()}" alt="captcha" onclick="this.src='{:captcha_src()}?id='+ new Date().getTime();" />
            </div>
          </div>
        </div>
      </div>

      <div class="layui-form-item">
        <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="demo-login">登录</button>
      </div>

    </div>
  </form>
</div>

<script src="__JS__/jquery.min.js"></script>
<script src="__STATIC__/layui/layui.js"></script>
<script src="__JS__/threeJs/three.js"></script>

<script type="text/javascript">
    $(function () {
        //判断一下当前是不是做顶层，如果不是，则做一下顶层页面重定向
        if (window != top) {
        top.location.href = location.href;
      }
  });

  layui.use(function(){
    var form = layui.form;
    var layer = layui.layer;
    // 提交事件
    form.on('submit(demo-login)', function(data){
      var field = data.field; // 获取表单字段值
      $.ajax({
        url: data.form.action,
        type: data.form.method,
        data: $(data.form).serialize(),
        success: function (info) {
          if (info.code === 1) {
             window.location.href = "{:url('Index/index')}"
          }else{
            $("#captcha").click()
          }
          layer.msg(info.msg);
        }
      });
      return false; // 阻止默认 form 跳转
    });
  });

</script>
<script type="x-shader/x-vertex" id="vertexshader">

			attribute float scale;

			void main() {

				vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

				gl_PointSize = scale * ( 300.0 / - mvPosition.z );

				gl_Position = projectionMatrix * mvPosition;

			}

		</script>

<script type="x-shader/x-fragment" id="fragmentshader">

			uniform vec3 color;

			void main() {

				if ( length( gl_PointCoord - vec2( 0.5, 0.5 ) ) > 0.475 ) discard;

				gl_FragColor = vec4( color, 1.0 );

			}

		</script>
<script type="importmap">
	{
        "imports":{
            "three":"__JS__/threeJs/three.module.js",
            "three/addons/": "__JS__/threeJs/jsm/"
        }
    }
		</script>

<script type="module">

  import * as THREE from 'three';



  const SEPARATION = 100, AMOUNTX = 50, AMOUNTY = 50;

  let container, stats;
  let camera, scene, renderer;

  let particles, count = 0;

  let mouseX = 0, mouseY =350;

  let windowHalfX = window.innerWidth / 2;
  let windowHalfY = window.innerHeight / 2;

  init();
  animate();

  function init() {

    container = document.createElement( 'div' );
    document.body.appendChild( container );

    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.z = 1000;

    scene = new THREE.Scene();

    //

    const numParticles = AMOUNTX * AMOUNTY;

    const positions = new Float32Array( numParticles * 3 );
    const scales = new Float32Array( numParticles );

    let i = 0, j = 0;

    for ( let ix = 0; ix < AMOUNTX; ix ++ ) {

      for ( let iy = 0; iy < AMOUNTY; iy ++ ) {

        positions[ i ] = ix * SEPARATION - ( ( AMOUNTX * SEPARATION ) / 2 ); // x
        positions[ i + 1 ] = 0; // y
        positions[ i + 2 ] = iy * SEPARATION - ( ( AMOUNTY * SEPARATION ) / 2 ); // z

        scales[ j ] = 1;

        i += 3;
        j ++;

      }

    }

    const geometry = new THREE.BufferGeometry();
    geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
    geometry.setAttribute( 'scale', new THREE.BufferAttribute( scales, 1 ) );

    const material = new THREE.ShaderMaterial( {

      uniforms: {
        color: { value: new THREE.Color( 0x16baaa ) },
      },
      vertexShader: document.getElementById( 'vertexshader' ).textContent,
      fragmentShader: document.getElementById( 'fragmentshader' ).textContent

    } );

    //

    particles = new THREE.Points( geometry, material );
    scene.add( particles );

    //

    renderer = new THREE.WebGLRenderer( { antialias: true,alpha: true } );
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild( renderer.domElement );



    window.addEventListener( 'resize', onWindowResize );

  }

  function onWindowResize() {

    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );

  }

  function animate() {

    requestAnimationFrame( animate );

    render();
    //stats.update();

  }

  function render() {

    camera.position.x += ( mouseX - camera.position.x ) * .05;
    camera.position.y += ( 350 - camera.position.y ) * .05;


    const positions = particles.geometry.attributes.position.array;
    const scales = particles.geometry.attributes.scale.array;

    let i = 0, j = 0;

    for ( let ix = 0; ix < AMOUNTX; ix ++ ) {

      for ( let iy = 0; iy < AMOUNTY; iy ++ ) {

        positions[ i + 1 ] = ( Math.sin( ( ix + count ) * 0.3 ) * 50 ) +
                ( Math.sin( ( iy + count ) * 0.5 ) * 50 );

        scales[ j ] = ( Math.sin( ( ix + count ) * 0.3 ) + 1 ) * 20 +
                ( Math.sin( ( iy + count ) * 0.5 ) + 1 ) * 20;

        i += 3;
        j ++;

      }

    }

    particles.geometry.attributes.position.needsUpdate = true;
    particles.geometry.attributes.scale.needsUpdate = true;

    renderer.render( scene, camera );

    count += 0.1;

  }

</script>
</body>
</html>